//package com.zy.config.common;
//
//import com.baomidou.dynamic.datasource.provider.AbstractJdbcDataSourceProvider;
//import com.baomidou.dynamic.datasource.provider.DynamicDataSourceProvider;
//import com.baomidou.dynamic.datasource.spring.boot.autoconfigure.DataSourceProperty;
//import com.baomidou.dynamic.datasource.spring.boot.autoconfigure.DynamicDataSourceProperties;
//import com.zy.db.utils.DataSourceUtils;
//import lombok.extern.slf4j.Slf4j;
//import org.springframework.context.annotation.Bean;
//import org.springframework.context.annotation.Configuration;
//import org.springframework.stereotype.Component;
//
//import java.sql.Connection;
//import java.sql.DriverManager;
//import java.sql.SQLException;
//import java.sql.Statement;
//import java.util.Map;
//import java.util.Set;
//import java.util.stream.Collectors;
//
//@Configuration
//@Slf4j
//@Component
//public class DatasourceConfig {
//
//    private final static String dynamic = "spring.datasource.dynamic";
//    private final static String datasource = "spring.datasource.dynamic.datasource";
//
//    /**
//     * 数据源自定义加载
//     *
//     * @param properties 数据源配置
//     * @return DynamicDataSourceProvider
//     */
//    @Bean
//    public DynamicDataSourceProvider dynamicDataSourceProvider(DynamicDataSourceProperties properties) {
//        Map<String, DataSourceProperty> datasourceMap = properties.getDatasource();
//        DataSourceProperty masterDataSourceProperty = datasourceMap.get(properties.getPrimary());
//        return new AbstractJdbcDataSourceProvider(masterDataSourceProperty.getDriverClassName(), masterDataSourceProperty.getUrl(), masterDataSourceProperty.getUsername(), masterDataSourceProperty.getPassword()) {
//            @Override
//            protected Map<String, DataSourceProperty> executeStmt(Statement statement) throws SQLException {
//                // 该地方只能使用statement操作数据库(数据源未加载,注入service操作数据库会出现循环依赖问题)
//                // 从数据库表记录读取数据库连接
//                String sql = " select t.* " +
//                        " from app_config_details t " +
//                        "         left join app_config t1 on t.app_config_id = t1.id " +
//                        " where t1.app_id = 'auth' " +
//                        "  and t1.env = 'dev' " +
//                        " and acd_key like '%spring.datasource.dynamic%' ";
//
//                Map<String, Object> map = DataSourceUtils.ResultSetToMap(statement.executeQuery(sql), "acd_key", "acd_value");
//                Set<String> names = map.keySet().stream().map(e -> {
//                    String name = e.replace("spring.datasource.dynamic.datasource.", "");
//                    return name.substring(0, name.lastIndexOf("."));
//                }).collect(Collectors.toSet());
//                names.stream().filter(x ->!x.equals(dynamic)).forEach(e ->{
//                    String username = String.format("%s.%s.username",datasource,e);
//                    String password = String.format("%s.%s.password",datasource,e);
//                    String url = String.format("%s.%s.url",datasource,e);
//                    addDatasource(e, map.get(username).toString(), map.get(password).toString(), map.get(url).toString(), "com.mysql.cj.jdbc.Driver", datasourceMap);
//                });
////                while (resultSet.next()) {
////                    String code = resultSet.getString("acd_key");
////                    String value = resultSet.getString("acd_value");
////                    map.put(code, value);
////                    if (!code.equals("spring.datasource.dynamic.primary")) {
////                        String name = code.replace("spring.datasource.dynamic.datasource.", "");
////                        log.info(name.substring(0, name.lastIndexOf(".")));
////                        names.add(name.substring(0, name.lastIndexOf(".")));
////                    }
//
////                    String username = resultSet.getString("spring.datasource.dynamic.datasource.master.username");
////                    String password = resultSet.getString("spring.datasource.dynamic.datasource.master.password");
////                    try {
////                        password = SecurityUtil.jiemi(password);
////                    } catch (Exception e) {
////                        log.warn("SecurityUtil.jiemi error, code:{}", code, e);
////                        continue;
////                    }
////                    String url = resultSet.getString("spring.datasource.dynamic.datasource.master.url");
////                    String driver = "com.mysql.cj.jdbc.Driver";// resultSet.getString("driver");
////                    addDatasource(code, username, password, url, driver, datasourceMap);
////                }
//
//
//                return datasourceMap;
//            }
//        };
//    }
//
//    private static void addDatasource(String code, String username, String password, String url, String driver, Map<String, DataSourceProperty> datasourceMap) {
//        if (!testConnection(code, username, password, url, driver)) {
//            return;
//        }
//        DataSourceProperty property = new DataSourceProperty();
//        property.setUsername(username);
//        property.setUrl(url);
//        property.setDriverClassName(driver);
//        property.setPassword(password);
//        datasourceMap.put(code, property);
//    }
//
//    private static boolean testConnection(String code, String username, String password, String url, String driver) {
//        log.info("test connection start. code:{}", code);
//        Connection var2 = null;
//        try {
//            Class.forName(driver);
//        } catch (ClassNotFoundException e) {
//            log.warn("class not found. code: {}", code, e);
//            return false;
//        }
//        try {
////            JdbcSecurityUtil.validate(url);
//            DriverManager.setLoginTimeout(3);
//            var2 = DriverManager.getConnection(url, username, password);
//            if (var2 == null) {
//                log.warn("connection fail. code: {}", code);
//                return false;
//            }
//            log.info("test connection success. code:{}", code);
//        } catch (Exception e) {
//            log.warn("connection error. code: {}", code, e);
//            return false;
//        } finally {
//            try {
//                if (var2 != null && !var2.isClosed()) {
//                    var2.close();
//                }
//            } catch (SQLException e) {
//                log.warn(e.toString());
//            }
//        }
//        return true;
//    }
//}
//
